package com.wyz.module.config.security.service;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.web.SecurityFilterChain;


/**
 * @author 无涯子
 * @date 2024/4/20
 */
@Configuration
public class WebSecurityConfig {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        // 认证
        http.authorizeRequests(authorize -> authorize
//                        .requestMatchers("/users/list").hasAnyAuthority("USER_LIST")
                        // 所有的请求开启认证
                        .anyRequest()
                        // 已认证的自动授权
                        .authenticated()
                );
        // 登录相关
        http.formLogin(from -> {
            // 修改登录页面
            from.loginPage("/login")
                    // 登录页面请求不需要校验
                    .permitAll()
                    .passwordParameter("mypassword")
                    .usernameParameter("myusername")
                    .failureUrl("/login?fail")
                    // 登录成功返回
                    .successHandler(new MyAuthenticationSuccessHandler())
                    // 登录失败返回
                    .failureHandler(new MyAuthenticationFailureHandler());
        });

        // 登出相关
        http.logout(logout -> {
            // 登出成功返回
            logout.logoutSuccessHandler(new MyLogoutSuccessHandler());
        });

        // 异常相关
        http.exceptionHandling(exception -> {
            // 请求为认证返回
            exception.authenticationEntryPoint(new MyAuthenticationEntryPoint())
                    .accessDeniedHandler(new MyAccessDeniedHandler());
        });

        // 会话管理
        http.sessionManagement(session -> {
            session
                    // 一个账号最多允许一个人登录
                    .maximumSessions(1)
                    // 会话过期提示
                    .expiredSessionStrategy(new MySessionInformationExpiredStrategy());
        });

        // 跨域
        http.cors(Customizer.withDefaults());

        // 关闭csrf攻击防御
        http.csrf(AbstractHttpConfigurer::disable);

        return http.build();
    }
}
